package com.hnd.springframework.beans.factory.support;

import com.hnd.springframework.BeansException;
import com.hnd.springframework.beans.factory.config.BeanDefinition;

import java.lang.reflect.Constructor;

/**
 * 负责创建bean实例
 */
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory {
    //    InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantittionStrategy();
    InstantiationStrategy instantiationStrategy = new SimpleInstantiationStrategy();


    @Override

    public Object createBean(String beanName, BeanDefinition beanDefinition, Object... args) throws BeansException {
        Object bean = null;
        try {
            bean = createBeanInstance(beanDefinition, beanName, args);
        } catch (BeansException | NoSuchMethodException e) {
            throw new BeansException("Instantiation of bean failed", e);
        }
        return bean;
    }

    protected Object createBeanInstance(BeanDefinition beanDefinition, String beanName, Object... args) throws BeansException, NoSuchMethodException {
        Constructor constructorTouse = null;
        Class beanClass = beanDefinition.getBeanClass();

        Constructor[] constructors = beanClass.getDeclaredConstructors();
        for (Constructor constructor : constructors) {
            if (null != args && constructor.getParameterTypes().length == args.length) {
                constructorTouse = constructor;
            }
        }

        return instantiationStrategy.instance(beanDefinition, beanName, constructorTouse, args);
    }
}
